Compilers are typically used to compile one computer program into another computer program--that is, to convert program instructions in one format in a computer program into another format in the other program. Put another way, compilers may also be considered to compile a computer program from one representation of the computer program to another representation of the computer program, where the different representations are themselves other computer programs, but are intended to perform basically the same computer operations.
Typically, a computer program is first written in a human-readable format, known as source code. Program instructions in the computer program are presented in the form of alphanumeric statements, and may include text labels that a programmer uses to identify variables and functions, as well as comments that the programmer includes to explain how the program works. The source code representation is then passed through a compiler to generate a machine-readable computer program, often known as object code, that can be directly executed by the computer system.
One principal advantage of compilers is that they often enable computer programs to be written in a single source code representation, and then compiled into different object code computer programs that can be executed on different computer systems. Computer systems are also referred to as platforms, and it is common to refer to a computer program that is able to execute on a particular computer system as being "native" to that platform.
It is often desirable to be able to recompile, or "port", a computer program originally written for execution on one platform to create a new computer program capable of being executed on another platform. Often, substantial development efforts are saved since a programmer does not have to start from scratch when adapting a computer program for execution on the new platform.
Computer programs may be ported to other manufacturers' platforms; however, an often more desirable task is to port computer programs written for one manufacturer's platform for execution on new platforms from the same manufacturer. In particular, it should be appreciated that a substantial amount of computer software may have been developed for a given platform, and it is often desirable to be able to adapt such software for use on later platforms.
From the user perspective, the most desirable alternative is to maintain backward compatibility in later platforms such that object code computer programs from an earlier platform may be executed on later platforms without any modification. However, this may not be possible in some instances due to underlying hardware or operating system changes on the later platforms.
For example, one change that may substantially hamper the ability of a native computer program for an earlier platform to execute on a later platform is a change in address space, e.g., a change from 32-bit addressing to 64-bit addressing. In particular, any computer system typically includes memory storage with an address space representative of a number of storage locations accessed by unique identifiers known as memory addresses. By referring to the memory address for a storage location, a computer system is able to write information into the storage location or read information from the storage location.
The number of storage locations, and thus, the size of the memory storage, is limited by the number of unique memory addresses available in a particular addressing space. For example, in 32-bit addressing, 32 binary bits are used to identify a particular storage location, indicating that the address space has a "width" of 32 bits. As a result, a maximum of 2.sup.32 unique combinations are possible, thereby providing a maximum of a little over 4 trillion unique storage locations. In many computer systems, storage locations are typically considered to hold eight binary bits, or one byte, of information each, and thus, 32-bit addressing provides a 4-gigabyte (GB) address space.
As the complexity and power of computer systems continue to increase, greater address spaces are required--particularly in networked environments where multiple users often share a common address space. Consequently, many platforms are now being designed to operate with 64-bit addressing, where a maximum of 2.sup.64 combinations of bits, and thus, over 18,000,000,000,000,000,000 unique storage locations are permitted.
A compiler typically requires information processed in a computer program to be classified into a particular data type, as some types of information may need to be handled differently than others. For example, strings of alphanumeric characters are typically stored and processed differently than numbers.
One commonly-used data type in many computer programs is a pointer, which is essentially a memory address that "points" to a particular storage location in memory. Pointers are principally used to dynamically allocate memory during execution of a computer program so that the amount of memory used by a computer program can vary with the needs of the program. Upon initialization of a pointer, the pointer is typically assigned to the memory address of a free storage location. This enables a computer program to use storage locations without concern for the particular addresses of those locations.
One characteristic of many computer platforms is that pointers are often the same width (i.e., they have the same number of bits) as the basic numeric data type, the integer. This is often due to the fact that optimal performance occurs when both data types occupy the full width of various information buses for the platform. Moreover, since both data types occupy the same width, the data types are often considered to be the same data type for certain operations. For example, many pointer arithmetic operations such as incrementing, decrementing, assignment, etc., are often treated as integer operations by both programmers and compilers alike.
The relationship between pointer and integer data types was maintained from the days of 8-bit and 16-bit addressing, and continued through to 32-bit addressing. However, in the following generation of computer platforms having 64-bit addressing, this relationship does not always hold true. In particular, the integer data type in many such systems is maintained at 32 bits in width, while the pointer data type is expanded to 64 bits in width.
As a result of previous reliance on the compatibility between pointer and integer data types, many computer programs native to 32-bit platforms are not easily ported to 64-bit platforms since many of the arithmetic operations performed on pointers on the 32-bit computer programs are no longer permitted on 64-bit platforms. Often, significant development efforts, and specifically, manual modifications to the earlier programs, are required.
Consequently, a significant need exists for a manner of facilitating the porting of computer programs written for specific platforms to permit execution of such programs on other platforms.